//
// afix_stack.c
//

#include "chlds_stack.h"
#include "chlds_memory.h"

#ifdef __cplusplus
extern "C" {
#endif

sint32 stack_create(TStack* pStack, const sint32 elen)
{
    pStack->used = 0;
    pStack->elen = elen;
    pStack->size = 16;
    pStack->base = MEMORY_ALLOC(pStack->size * pStack->elen);
    MEMORY_ZERO(pStack->base, pStack->size * pStack->elen);

    return 0;
}

sint32 stack_release(TStack* pStack)
{
    MEMORY_FREE(pStack->base);
    pStack->base = NULL;
    pStack->used = 0;
    pStack->elen = 0;
    pStack->size = 0;

    return 0;
}

sint32 stack_extend(TStack* pStack)
{
    void* p = MEMORY_ALLOC(pStack->size * pStack->elen * 2);
    MEMORY_ZERO(p, pStack->size * pStack->elen * 2);
    MEMORY_COPY(p, pStack->base, pStack->size * pStack->elen);

    MEMORY_FREE(pStack->base);
    pStack->base = p;
    pStack->size *= 2;

    return 0;
}

sint32 stack_push(TStack* pStack, const void* p)
{
    MEMORY_COPY(MEMORY_OFFSET(pStack->base, pStack->used, pStack->elen), p, pStack->elen);
    /*MEMORY_COPY((clt_byte*)(pStack->base) + (pStack->used * pStack->elen), p, pStack->elen);*/
    pStack->used++;

    if (pStack->used == pStack->size)
        stack_extend(pStack);

    return 0;
}

void* stack_pop(TStack* pStack)
{
    if (0 == pStack->used)
        return NULL;

    pStack->used--;
    return MEMORY_OFFSET(pStack->base, pStack->used, pStack->elen);
    /*return ((clt_byte*)(pStack->base) + (pStack->used) * pStack->elen);*/
}

sint32 stack_used(const TStack* pStack)
{
    return pStack->used;
    /*if (pStack->used)
        return 0;
    else
        return 1;*/
}

#ifdef __cplusplus
}
#endif
